// 事件总线，发布订阅模式
class EventEmitter {
  constructor() {
    this.cache = {};
  }
  on(name, fn) {
    if (this.cache[name]) {
      this.cache[name].push(fn);
    } else {
      this.cache[name] = [fn];
    }
  }
  off(name, fn) {
    let tasks = this.cache[name];
    if (tasks) {
      const index = tasks.findIndex((f) => f === fn || f.callback === fn);
      if (index >= 0) {
        tasks.splice(index, 1);
      }
    }
  }
  emit(name, once = false, ...args) {
    if (this.cache[name]) {
      // 创建副本，如果回调函数内继续注册相同事件，会造成死循环
      let tasks = this.cache[name].slice();
      for (let fn of tasks) {
        fn(...args);
      }
      if (once) {
        delete this.cache[name];
      }
    }
  }
}

// 测试
let eventBus = new EventEmitter();
let fn1 = function (name, age) {
  console.log(`${name} ${age}`);
};
let fn2 = function (name, age) {
  console.log(`hello, ${name} ${age}`);
};
eventBus.on("aaa", fn1);
eventBus.on("aaa", fn2);
eventBus.emit("aaa", false, "布兰", 12);
// '布兰 12'
// 'hello, 布兰 12'

// 实现一个简单的EventEmitter
// 实现一个简单的观察者对象
class MyObject {
  constructor() {
    this.events = {};
  }
  on(eventname, fu) {
    if (!this.events[eventname]) {
      this.events[eventname] = [];
    }
    this.events.push(fn)
  }
  emit(eventname, ...rest) {
    if (this.events[eventname]) {
      this.events[eventname].forEach(element => {
        element(...rest);
      });
    }
  }
  off(eventname, fn) {
    if (this.events[eventname]) {
      this.events[eventname] = this.events[eventname].filter((item, index) => {
        return item !== fn;
      })
    }
  }
  once(eventname, fn) {
    const temp = (...rest) => {
      fn(...rest);
      this.off(eventname, fn)
    }
    this.on(eventname, temp)
  }
}